package com.joelbitar.switchctrl;

import java.util.ArrayList;

import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

public class switchctrl extends ListActivity {
	/** Menu Stuffs*/
	private static final int MENU_SETTINGS = 0;
	private static final int MENU_HELP = 1;
	private static final int MENU_REFRESH = 2;
	private static final int MENU_SEND = 3;

	private static final int GET_TAG_SWITCH_BUTTON = 3;
	private static final int GET_TAG_TOGGLE_BUTTON = 3;
	
	private DevicesListAdapter deviceAdapter;
	private ArrayList<Device> devices = null;
	
	private Request request = new Request();
	private int requestsPending = 0;
	
	public static Preferences preferences;
	
    private class executeRequests extends AsyncTask<Request, Integer, Response>{
		@Override
		protected Response doInBackground(Request... requests) {
			// ONLY one request send, always.
			// Execute the request
	    	Webservice webservice = new Webservice();
	    	Response response = webservice.getResponse(requests[0]);
		    
	    	requestsPending += 1;

	    	// Pass the response to the onPostExecute thingy
	    	return response;
		}
	     protected void onPostExecute(Response response) {
	    	 requestsPending -= 1;
	    	 
	    	 updateViewFromResponse(response);
	     }
    }
    
    
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //requestWindowFeature(Window.FEATURE_PROGRESS);
        
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setProgressBarIndeterminateVisibility(true);
        //setProgressBarIndeterminateVisibility(true);

        setContentView(R.layout.main);
        
        //setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, 1);
        
       // setProgressBarVisibility(true);
        //setProgressBarVisibility(false);
        
        this.devices = getActiveDevices();
        
        deviceAdapter = new DevicesListAdapter(this, R.layout.device_switch, devices);
        
        this.preferences = new Preferences(getBaseContext());
        
        setListAdapter(deviceAdapter);
    }
    
    public void clearRequest() {
    	this.request.clear();
    	this.deviceAdapter.clearMarked();
    	this.deviceAdapter.notifyChange();
	}
    
    public void notifyRequestImplications(ArrayList<Request> requests) {

    	int onCount = 0;
    	int offCount = 0;
    	
    	if(requests.size() > 0)
    	{
    		Log.i("requestssize", "More than 0");
    		for(int i = 0; i < requests.size(); i += 1)
    		{
    			Log.i("executingrequest", "Executing requst");
    			onCount = request.getOn().size();
    			offCount = request.getOff().size();
    		}
    	}
    	
    	
    	// Something in the toasting crap is fucking up the multi-send thingy only with different on/offs
    	if(onCount > 0 && offCount > 0)
    	{

    		Resources res = getResources();

    		String on = String.format(res.getQuantityString(R.plurals.message_devices_turning_number_of_lights, onCount), onCount);
    		String off = String.format(res.getQuantityString(R.plurals.message_devices_turning_number_of_lights, offCount), offCount);
    		
    		Log.i("on", on);
    		Log.i("off", off);
    		
    		String toast = String.format(getString(R.string.message_devices_turning_on_and_off), on, off);
    		
    		
    		
    		this.makeToast(toast);
    		
    	}
    	else if(onCount > 0 && offCount == 0)
    	{
    		if(onCount == 1)
    		{
    			this.makeToast
    			(
    					String.format
    					(
    							getString
    							(
    									request.getOn().get(0).getRequestInProgressTextResource()
    							)
    							,
    							request.getOn().get(0).getName()
    					)
    			);
    		}
    		else
    		{
        		this.makeToast(String.format(getString(R.string.message_devices_turning_on), onCount));
    		}
    	}
    	else if(offCount > 0 && onCount == 0)
    	{
    		if(offCount == 1)
    		{
    			this.makeToast
    			(
    					String.format
    					(
    							getString
    							(
    									request.getOff().get(0).getRequestInProgressTextResource()
    							)
    							,
    							request.getOff().get(0).getName()
    					)
    			);
    		}
    		else
    		{
        		this.makeToast(String.format(getString(R.string.message_devices_turning_off), offCount));
    		}
    	}
    	else
    	{
    		this.makeToast(getString(R.string.message_devices_no_devices));
    	}
    	
    }
    
    public void executeRequestQue()
    {
    	Log.i("executerequest", "Going to execute requests");
    	
    	// Mark All devices with True
    	this.markDevicesRequestInProgress(this.request, true);
    	
    	ArrayList<Request> requests = this.request.splitRequest();
    	
    	this.notifyRequestImplications(requests);
    	
    	this.executeRequests(requests);
    	// Clear the request object and all the markings. Also update the ui
    	this.clearRequest();
    }
    
    // set the requestInProgress variable on all devices in the request to true/false 
    private void markDevicesRequestInProgress(Request request, boolean requestInProgress) {
		
    	// All the devices in the request
    	ArrayList<Device> devices = request.getAllDevices();
    	
    	// if one or more
    	if(devices.size() > 0)
    	{
    		// Loop thru them and Set everyone to the passed variable
    		for(int i = 0; i < devices.size(); i += 1)
    		{
    			// Get current device
    			Device device = devices.get(i);
    			
    			if(requestInProgress)
    			{
    				// If device in the requests OFF list
    				if(request.getOff().contains(device))
        			{
    					// Set the device request status to off
        				device.setRequestStatus(Device.REQUEST_STATUS_OFF);
        			}
    				// IF device is in the request OFF list
        			else if(request.getOn().contains(device))
        			{
        				// Set device request status to on
        				device.setRequestStatus(Device.REQUEST_STATUS_ON);
        			}
    			}
    			else
    			{
        			device.setRequestStatus(Device.REQUEST_STATUS_NONE);
    			}

				// Set the requestInProgress boolean to x
    			device.setRequestInProgress(requestInProgress);
    			
    			
    		}
    	}
    	
	}

	public void executeRequests(ArrayList<Request> requests)
    {
    	if(requests.size() > 0)
    	{
    		Log.i("requestssize", "More than 0");
    		for(int i = 0; i < requests.size(); i += 1)
    		{
    			Log.i("executingrequest", "Executing requst");
    			
    			new executeRequests().execute(requests.get(i));
    		}
    	}
    }
    
    
	private void updateViewFromResponse(Response response) {
		Request request = response.getRequest();

   	 
   	 	//setProgressIsVisible();
   	 
		// Mark all devices as request is finished, which is is! (yay)
		this.markDevicesRequestInProgress(request, false);
		
    	if(response.isSuccess())
    	{
    		Log.i("switchctrl", "Response is success");

    		ArrayList<Device> onDevices = request.getOn();
    		ArrayList<Device> offDevices = request.getOff();

    		if(onDevices.size() > 0)
    		{
    			Log.i("ondevices", "Several on devices");
    			for(int i = 0; i < onDevices.size(); i += 1)
    			{
    				Device on = onDevices.get(i);
    				Log.i("on", on.getName());
    				on.setStatus(1);
    			}
    		}

    		if(offDevices.size() > 0)
    		{
    			Log.i("offdevices", "Several off devices");
    			for(int i = 0; i < offDevices.size(); i += 1)
    			{
    				Device off = offDevices.get(i);
    				Log.i("on", off.getName());
    				off.setStatus(0);
    			}
    		}
    		
    		deviceAdapter.notifyDataSetChanged();
    	}
    	else
    	{
    		Log.e("switchctrl", "Response is a failiure");
    	}
    	
    	request.clear();
	}
    
	private View getMainView(View view, int times)
	{
    	for(int i = 1; i <= times; i += 1)
    	{
        	view = (View) view.getParent();
    	}
		
    	return view;
	}
	
    private Device getDeviceFromTag(View view, int times)
    {
    	Device device = (Device) this.getMainView(view, times).getTag();
    	return device;
    }
    
    public void resetSwitchStatus(View view, int times)
    {
    	View mainView = this.getMainView(view, times);
    	
    	ImageView button;

    	button = (ImageView) mainView.findViewById(R.id.on_button);
    	button.setImageResource(R.drawable.switch_on_inactive);
    	
    	button = (ImageView) mainView.findViewById(R.id.off_button);
    	button.setImageResource(R.drawable.switch_off_inactive);
    }
    
    public void switchToggleClick(View view)
    {
    	
    	view = this.getMainView(view, switchctrl.GET_TAG_TOGGLE_BUTTON);
    	
    	
    	Device device = (Device) view.getTag();
    	Server server = device.getServer();
    	
    	request.setServer(server);
    	
    	if(device.getStatus() == 1)
    	{
    		request.addOff(device);
    	}
    	else
    	{
    		request.addOn(device);
    	}
    	
    	this.makeBuzz();
    	this.executeRequestQue();
    }
    
    
    
    public void switchOnClick(View view){
    	Device device = this.getDeviceFromTag(view, GET_TAG_SWITCH_BUTTON);
    	
    	if(device.getType() == Device.TYPE_SWITCH)
    	{
    		if(device.getMarked() == 1)
    		{
    			device.setMarked(-1);
    			this.request.removeFromOnList(device);
    			this.request.removeFromOffList(device);
    		}
    		else
    		{
    			device.setMarked(1);
    			this.request.removeFromOffList(device);
    			this.request.addOn(device);
    		}
    	}
    	Log.i("bah", device.getName());
    	

    	this.makeBuzz();
    	this.deviceAdapter.notifyChange();
    }
    
    public void switchOffClick(View view){
    	Device device = this.getDeviceFromTag(view, GET_TAG_SWITCH_BUTTON);
    	
    	if(device.getType() == Device.TYPE_SWITCH)
    	{
    		if(device.getMarked() == 0)
    		{
    			device.setMarked(-1);
    			this.request.removeFromOffList(device);
    			this.request.removeFromOnList(device);
    		}
    		else
    		{
    			device.setMarked(0);
    			this.request.removeFromOnList(device);
    			this.request.addOff(device);
    		}
    	}

    	this.makeBuzz();
    	this.deviceAdapter.notifyChange();
    	
    	Log.i("bah", device.getName());
    	
    }
    
    public void clearMarked(View view) {
    	this.deviceAdapter.clearMarked();
    	this.request.clear();
    	this.deviceAdapter.notifyChange();
    }
    
    private void updateActiveDevices() {
    	/*
    	Webservice webservice = new Webservice();
    	
    	ArrayList<Request> requests = webservice.getAllActiveDevicesRequests();
    	
    	this.executeRequests(requests);
    	*/
    	
        this.devices = getActiveDevices();
        
        this.deviceAdapter.updateDevices(this.devices);
        
        this.makeToast(getString(R.string.message_devices_updated));
        
    }

    public void makeToast(String toastText){
        Context context = getApplicationContext();
        CharSequence text = toastText;
        Toast toast = Toast.makeText(context, text, Toast.LENGTH_LONG);
        toast.show();
    }
    
    public void makeBuzz()
    {
    	int vibrationLength = (Integer) this.preferences.get(Preferences.VIBRATE_LENGTH).getValue();
    	
    	Log.i("vibrationlength", "" + vibrationLength);
    	
    	if(vibrationLength > 0)
    	{
        	Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
    		vibrator.vibrate(vibrationLength);
    	}
    }
    // The main application menu
    public boolean onCreateOptionsMenu(Menu menu)
    {
    	menu.add(0, MENU_HELP, 0, getString(R.string.menu_main_help)).setIcon(android.R.drawable.ic_menu_help);
    	menu.add(0, MENU_SETTINGS, 0, getString(R.string.menu_main_settings)).setIcon(android.R.drawable.ic_menu_preferences);
    	menu.add(0, MENU_REFRESH, 0, getString(R.string.menu_main_refresh)).setIcon(android.R.drawable.ic_menu_rotate);
    	
    	return true;
    }
	
    /* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
		    case MENU_SETTINGS:
		    	startSettingsActivity();
		        return true;
		    case MENU_REFRESH:
		    	updateActiveDevices();
		    	return true;
		    case MENU_HELP:
		    	startSettingsActivity();
		    	return true;
	    }
	    return false;
	}
	
	public boolean startSettingsActivity() {
		
		Intent myIntent = new Intent();
		//myIntent.setClassName("com.android.samples", "com.android.samples.Animation1");
		myIntent.setClassName("com.joelbitar.switchctrl", "com.joelbitar.switchctrl.settings");
		startActivity(myIntent);    
		
		return true;
	}
	
	public void menuSendRequestButtonPress(View v)
	{
		this.executeRequestQue();
	}
	
	private ArrayList<Device> getActiveDevices() {
		Webservice webservice = new Webservice();
		webservice.setContext(getApplicationContext());
		
		ArrayList<Device> devices = webservice.getAllActiveDevices();
		
		Log.w("getdevices", "Devices");
		for(int i = 0; i < devices.size(); i += 1)
		{
			Device device = devices.get(i);
			Log.i("id", "" + device.getId());
			Log.i("type", "" + device.getType());
			Log.i("name", "" + device.getName());
			Log.i("status", "" + device.getStatus());
		}
		
		return devices;
	}
}
